home *** CD-ROM | disk | FTP | other *** search
-
- ;MAKEBIN HEADER; COMPILE WITH SEATTLE ASSEMBLER
- ;MAKEBIN HEADER V1.01 Copyright 1989 Michael Day as of 16 April 1989
-
- FILSIZE EQU 2
- ITEMCNT EQU 6
- HDRSIZE EQU 8
- STKSEG EQU 0EH
- STKOFF EQU 10H
- CODEOFF EQU 14H
- CODESEG EQU 16H
- RELITEM EQU 18H
-
- ;FLAGS,CS,IP,AX,BX,CX,DX,SI,DI,DS,ES,BP,SP,SS
-
- ORG 0 ;WE ASSUME THAT WE WILL BE LOADED
- ENTRY: ;ON A SEGMENT BOUNDRY
- SEG CS
- MOV [OLDDS],DS ;SAVE CURRENT DS
- PUSH CS ;THEN UPDATE IT TO OUR CS
- POP DS
- MOV [OLDSS],SS
- MOV [OLDSP],SP
- MOV [OLDBP],BP
- MOV [OLDES],ES
- MOV [OLDDI],DI
- MOV [OLDSI],SI ;SAVE ALL REGISTERS
- MOV [OLDDX],DX
- MOV [OLDCX],CX
- MOV [OLDBX],BX
- MOV [OLDAX],AX
- PUSHF
- POP AX
- MOV [OLDFLGS],AX
-
- MOV AX,[BIPC]
- OR AX,AX ;CHECK IF ALREADY CONVERTED
- JZ FIXUP
- JMP MAKPSP ;ALREADY CONVERTED, SO JUST DO IT
-
- FIXUP:
- MOV SI,FILEBEG
- MOV DX,SI ;SI POINTS AT EXE HEADER
- MOV CL,4
- ROR DX,CL ;DX CONTAINS NEW BASE SEGMENT
- AND DX,0FFFH
- MOV AX,CS
- ADD DX,AX
- ADD DX,[SI+HDRSIZE]
- MOV CX,[SI+ITEMCNT] ;NUMBER OF SEGMENTS TO CONVERT
- MOV BX,[SI+RELITEM] ;BX POINTS AT ITEM TO CONVERT
- ADD BX,SI
-
- MOV AX,[SI+CODESEG]
- ADD AX,DX
- MOV [WRKCS],AX
- MOV [EXECS],AX
- MOV AX,[SI+CODEOFF] ;SET FAR CALL ADDRESS
- MOV [WRKIP],AX
- MOV [EXEIP],AX
-
- MOV AX,4942H
- MOV [BIPC],AX ;MARK THE HEADER
- MOV AX,4350H ;CONVERT = NON-ZERO
- MOV [BIPC2],AX ;INDICATES IT IS CONVERTED
-
- MAKREL:
- LES DI,[BX] ;MANGLE THE CODE TO GET THE
- MOV AX,ES ;SEGMENT ADDRESSES RIGHT
- ADD AX,DX
- MOV ES,AX
- SEG ES
- ADD [DI],DX
- ADD BX,4
- LOOP MAKREL
-
- MOV AX,[SI+FILSIZE] ;SAVE PROGRAM SIZE
- MOV [PRGSIZ],AX
-
- MOV AX,[SI+STKSEG]
- ADD AX,DX ;CREATE THE STACK
- MOV [WRKSS],AX ;BASED ON THE EXE INFO
- MOV [EXESS],AX
- MOV [BINSS],AX
- MOV AX,[SI+STKOFF]
- MOV [WRKSP],AX
- MOV [EXESP],AX
- MOV [BINBP],AX
-
- SUB DX,16
- MOV [PSPSEG],DX ;SAVE OUR PSP POINTER
- MOV [BINDS],DX ;WE WILL POINT DS THERE ON ENTRY
- MAKPSP:
- CALL CHGCHK ;CHECK FOR ENTRY ADR CHANGE
- JNZ SKIPSP ;WARM ENTRY, DON'T RE-CREATE PSP
-
- MOV DX,[PSPSEG] ;GET A COPY OF PSP IN DX
- MOV AX,DX ;CLEAR THE PSP
- SUB AX,2 ;PLUS 32 BYTES BELOW IT
- MOV DS,AX
- XOR BX,BX
- MOV CX,256+16+16 ;CLEAR PSP, MCB, AND WORK AREA
- CLRIT:
- MOV B,[BX],0
- INC BX
- LOOP CLRIT
-
- XOR BX,BX
- MOV [BX],DATATAB ;STORE POINTER TO DATA TABLE
- MOV [BX+2],CS
-
- MOV BX,16
- MOV [BX],5AH ;DUMMY END MCB
- MOV [BX+1],DX ;WE ARE THE OWNER
- SEG CS
- MOV AX,[PRGSIZ]
- MOV [BX+3],AX ;HOW BIG IT IS
-
- MOV DS,DX
- MOV CX,11 ;CLEAR FCB1 & FCB2 AREA
- XOR BX,BX
- CLRFCB1:
- MOV B,[BX+5DH],20H
- MOV B,[BX+6DH],20H
- INC BX
- LOOP CLRFCB1
-
- MOV AH,62H ;GET CURRENT PSP SEG
- INT 21H ;IN BX
- MOV CX,15H ;COPY BEG OF THIER PSP TO OURS
- XOR SI,SI
- CALL CPYPSP
-
- SEG CS
- MOV AX,[PRGSIZ] ;UPDATE THE END OF MEMORY
- MOV CX,ES ;FOR OUR PSP
- ADD AX,CX ;LAST SEG = LENGTH OF PRG + CS
- SEG ES
- MOV [2],AX
-
- SEG ES
- MOV B,[80H],1EH ;SET CMD LINE LENGTH BYTE
-
- SKIPSP:
- MOV AH,62H ;GET CURRENT PSP SEG
- INT 21H ;IN BX
- SEG CS
- MOV [OLDPSP],BX ;SAVE CALLERS PSP
-
- MOV CX,45H ;GET COPY OF CALLER'S ENV,
- MOV SI,16H ;HANDLE TABLE, AND PID.
- CALL CPYPSP
-
- MOV AH,50H
- SEG CS
- MOV BX,[PSPSEG] ;SET DOS TO OUR OWN PSP
- INT 21H
-
- MOV BX,20H
- MOV DI,OLD20 ;SWAP TERMINATE ADDRESS
- MOV AX,INTRET ;WITH OUR OWN
- CALL SETINT
-
- MOV BX,27H
- MOV DI,OLD27 ;SWAP DOS TSR VECTOR
- MOV AX,INTRET ;WITH OUR OWN (SAME AS NORMAL EXIT)
- CALL SETINT
-
- MOV BX,21H
- MOV DI,OLD21 ;SWAP DOS INT VECTOR
- MOV AX,MYDOS ;WITH OUR OWN
- CALL SETINT
-
- PUSH CS
- POP DS
- CMP W,[WRKSS],0 ;DON'T SWITCH IF ZERO
- JZ NOSTACK
- CLI
- MOV SS,[WRKSS] ;SWITCH THE STACK
- MOV SP,[WRKSP]
- STI
- NOSTACK:
- MOV AX,CFRET ;SAVE OUR RETURN ADDRESS ON STACK
- PUSH CS
- PUSH AX
- PUSH [WRKCS] ;PUSH EXE ENTRY ON STACK
- PUSH [WRKIP]
- MOV BP,[BINBP] ;SET UP BP TO POINT AT WHERE-EVER
- MOV ES,[PSPSEG] ;SET UP ES TO POINT AT PSP
- MOV DS,[BINDS] ;SET UP DS TO POINT AT WHERE-EVER
- RET L ;ENTER THE EXE PRG VIA STACK
-
- ;---------------------------------------------------------------
- ; upon completion of the EXE program we return to here
-
- CFRET:
- SEG CS ;FAR CALL RETURN
- MOV [BINDS],DS ;SAVE CURRENT DS FOR RE-ENTRY
- WARMRET:
- SEG CS ;WARM START = ENTRY POINT WAS CHANGED
- MOV [WRKSS],SS ;USE THE CURRENT STACK FOR WARM RE-ENTRY
- SEG CS
- MOV [WRKSP],SP
- DORET:
- SEG CS
- MOV [BINBP],BP ;ALSO SAVE BP
- SEG CS
- MOV [BINSS],SS ;SAVE OUR STACK SEG TOO
-
- MOV BX,20H
- MOV DI,OLD20 ;RESTORE OLD INT 20H
- CALL CLRINT
-
- MOV BX,21H
- MOV DI,OLD21 ;RESTORE OLD INT 21H
- CALL CLRINT
-
- MOV BX,27H
- MOV DI,OLD27 ;RESTORE OLD INT 27H
- CALL CLRINT
-
- MOV AH,50H
- SEG CS
- MOV BX,[OLDPSP] ;RESTORE CALLERS PSP
- INT 21H
-
- PUSH CS
- POP DS
- CLI
- MOV SS,[OLDSS]
- MOV SP,[OLDSP]
- STI
- MOV BP,[OLDBP]
- MOV ES,[OLDES]
- MOV DI,[OLDDI]
- MOV SI,[OLDSI] ;RESTORE ALL REGISTERS
- MOV DX,[OLDDX]
- MOV CX,[OLDCX]
- MOV BX,[OLDBX]
- MOV AX,[OLDFLGS] ;RESTORE FLAGS
- PUSH AX
- POPF
- MOV AX,[OLDAX]
- MOV DS,[OLDDS] ;RESTORE DS
- RET L ;AND GO HOME
-
- INTRET:
- SEG CS
- MOV [BINDS],DS ;SAVE CURRENT DS FOR RE-ENTRY
- PUSH CS
- POP DS
- CALL CHGCHK ;CHECK FOR ENTRY ADR CHANGE
- JNZ WARMRET ;WARM START IF CHANGED]
-
- MOV AX,[PSPSEG] ;IT WAS A COLD RETURN,
- MOV [BINDS],AX ;SO RESTORE ALL REGISTERS
- MOV AX,[EXESS] ;TO START UP CONDITION
- MOV [WRKSS],AX
- MOV AX,[EXESP]
- MOV [WRKSP],AX
- JMP DORET
-
- DOMEM:
- MOV AX,8
- XOR BX,BX ;TELL THEM THEY CAN'T ALLOCATE MEMORY
- STC
- IRET
-
- MYDOS:
- CMP AH,0 ;ZERO TERMINATE
- JZ INTRET
- CMP AH,4CH ;ALTERNATE TERMINATE
- JZ INTRET
- CMP AH,31H ;TSR TERMINATE
- JZ INTRET
- CMP AH,48H ;ALLOC MEM
- JZ DOMEM
- CMP AH,49H ;FREE MEM
- JZ DOMEM
- CMP AH,4AH ;MODIFY MEM
- JZ DOMEM
- CMP AH,4BH ;LOAD AND EXEC
- JZ DOMEM
-
- SEG CS
- PUSH [OLD21S] ;PUSH OLD DOS ENTRY ON STACK
- SEG CS
- PUSH [OLD21]
- RET L ;AND RETURN TO IT
-
- ;COPY ALL OR PART OF CALLER'S PSP
- ;NOTE THAT OUR PSP IS NOT A CHILD PSP, BUT RATHER
- ;AN INDEPENDANT COPY OF THE PARENT PSP.
- CPYPSP:
- CLD
- MOV DS,BX
- SEG CS
- MOV ES,[PSPSEG]
- MOV DI,SI
- REP
- MOVSB
- RET
-
- ;CHECK IF ENTRY ADDRESS WAS CHANGED
- CHGCHK:
- MOV AX,[WRKCS] ;IF THEY CHANGED THE ENTRY, THEN
- CMP AX,[EXECS] ;WE DO A WARM RESTART INSTEAD
- JNZ CHGRET
- MOV AX,[WRKIP]
- CMP AX,[EXEIP]
- CHGRET:
- RET
-
- ;SWAP INTERRUPT VECTOR
- SETINT:
- XOR CX,CX ;DS POINTS AT INT VECTORS
- MOV DS,CX
- ADD BX,BX ;BX = INT NUMBER
- ADD BX,BX
- LES CX,[BX] ;GET CURRENT VALUE
- SEG CS
- MOV [DI],CX ;SAVE IT IN MEMORY DI = SAVE ADDR
- SEG CS
- MOV [DI+2],ES
- CLI
- MOV [BX],AX ;SET NEW VALUE AX = OFFSET
- MOV [BX+2],CS
- STI
- RET
-
- ;RESTORE INTERRUPT VECTOR
- CLRINT:
- XOR CX,CX ;DS POINTS AT INT VECTORS
- MOV DS,CX
- ADD BX,BX ;BX = INT NUMBER
- ADD BX,BX
- SEG CS
- LES CX,[DI] ;RECOVER OLD VALUE FROM MEM
- CLI
- MOV [BX],CX ;RESTORE OLD VECTOR CX = OFFSET
- MOV [BX+2],ES ;ES = SEGMENT
- STI
- RET
-
- ;*********************************************************
- ;THIS TABLE MUST REMAIN IN THIS ORDER FOR EXTERNAL ACCESS
-
- DATATAB EQU $
-
- BIPC DW 0 ;LOADER ID
- BIPC2 DW 0 ;CONVERSION FLAG (0 = NOT CONVERTED)
- OLDFLGS DW 0 ;CALLERS REGISTERS
- OLDAX DW 0
- OLDBX DW 0
- OLDCX DW 0
- OLDDX DW 0
- OLDSI DW 0
- OLDDI DW 0
- OLDDS DW 0
- OLDES DW 0
- OLDBP DW 0
- OLDSP DW 0 ;CALLERS STACK OFFSET
- OLDSS DW 0 ;CALLERS STACK SEGMENT
- WRKIP DW 0 ;POINTER TO CODE ENTRY
- WRKCS DW 0
- WRKSP DW 0 ;OUR STACK OFFSET
- WRKSS DW 0 ;OUR STACK SEGMENT
-
- BINDS DW 0 ;OUR OWN DS ON EXIT
- BINBP DW 0 ;OUR OWN BP ON EXIT
- BINSS DW 0 ;LAST KNOW STACK SEG
- EXEIP DW 0 ;ORIGINAL EXE ENTRY OFFSET
- EXECS DW 0 ;ORIGINAL EXE ENTRY SEGMENT
- EXESP DW 0 ;ORIGINAL EXE STACK OFFSET
- EXESS DW 0 ;ORIGINAL EXE STACK SEGMENT
- PSPSEG DW 0 ;OUR PSP SEG
- OLDPSP DW 0 ;PREV PSP SEG
- PRGSIZ DW 0 ;SIZE OF PROGRAM FILE IN PARAGRAPHS (SEG)
-
-
- ;**********************************************************
- ;END OF FIXED TABLE ACCESS
-
- OLD20 DW 0 ;PREV INT 20 OFFSET
- OLD20S DW 0 ;PREV INT 20 SEGMENT
- OLD21 DW 0 ;PREV INT 21 OFFSET
- OLD21S DW 0 ;PREV INT 21 SEGMENT
- OLD27 DW 0 ;PREV INT 27 OFFSET
- OLD27S DW 0 ;PREV INT 27 SEGMENT
-
-
- DS 256+16+16 ;MINIMAL STORAGE AREA FOR PSP+MCB+MISC
- PRGEND EQU $ ;MINIMUM HEADER SIZE NEEDED
-
- LAST EQU 400H ;MAKE THIS AT A SEGMENT BOUNDRY PAST PRGEND
-
- FILEBEG EQU LAST ;EXE IS LOADED AT SEGMENT BOUNDRY
-
- END